package org.bdware.irp.irplib.core;

import org.bdware.irp.irplib.core.IrpMessage;
import org.bdware.irp.irplib.core.IrpMessageHeader;
import org.bdware.irp.irplib.core.IrpMessageCode;
import org.bdware.irp.irplib.exception.IrpMessageDecodeException;
import org.bdware.irp.irplib.util.GlobalUtils;
import org.bdware.irp.irplib.util.EncoderUtils;

import com.nimbusds.jose.jwk.JWK;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class IrpResponse extends IrpMessage{
    public byte[] doid;
    public byte[][] doids;
    //public boolean isAuthNeeded;
    public boolean requestDigestNeeded;
    public byte[][] doidValues = null;
    public byte[][] doidArray = null;

    public byte[] requestDigest;
    public byte[] responseMessage;
    public static final int INT_SIZE = 4;

    public String result = "success";
    /**
     * Creates an IrpResponse.
     */
    public IrpResponse(int opCode, int resCode) {
        super(opCode, resCode);
        this.requestDigest = null;
    }
    public IrpResponse(int opCode, int resCode, String doid) {
        super(opCode, resCode);
        //this.authInfo = authInfo;
        if(doid!=null){
            this.doid = GlobalUtils.encodeString(doid);
        }
        this.requestDigest = null;
    }

    public static IrpResponse newIrsResolveResponse(String doid, Map<String,String> values) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_RESOLUTION_DOID, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        if(values != null) {
            res.doidValues = fromMap2Byte(values);
        }
        return res;
    }

    public static IrpResponse newIrsResolveResponse(byte[] doid, byte[][] values) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_RESOLUTION_DOID, IrpMessageCode.RC_SUCCESS);
        res.doid = doid;
        res.requestDigestNeeded = false;
        res.doidValues = values;
        return res;
    }

    public static IrpResponse newIrsCreateDoidResponse(String doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_CREATE_DOID, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newOrgCreateResponse(String doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_CREATE_ORG_GRS, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newOrgUpdateResponse(String doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_UPDATE_ORG_GRS, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newOrgDeleteResponse(String doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_DELETE_ORG_GRS, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newIrsCreateDoidResponse(byte[] doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_CREATE_DOID, IrpMessageCode.RC_SUCCESS);
        res.doid = doid;
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newIrsUpdateDoidResponse(String doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_UPDATE_DOID, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newIrsUpdateDoidResponse(byte[] doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_UPDATE_DOID, IrpMessageCode.RC_SUCCESS);
        res.doid = doid;
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newIrsDeleteDoidResponse(String doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_DELETE_DOID, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newIrsDeleteDoidResponse(byte[] doid) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_DELETE_DOID, IrpMessageCode.RC_SUCCESS);
        res.doid = doid;
        res.requestDigestNeeded = false;
        return res;
    }
    public static IrpResponse newIrsBatchCreateDoidResponse(List<String> doids) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_BATCH_CREATE_DOID, IrpMessageCode.RC_SUCCESS);
        int length = doids.size();
        res.doids = new byte[length][];
        int i = 0;
        for(String doidEl : doids){
            res.doids[i] = GlobalUtils.encodeString(doidEl);
            i++;
        }
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newIrsBatchCreateDoidResponse(byte[][] doids) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_BATCH_CREATE_DOID, IrpMessageCode.RC_SUCCESS);
        res.doids = doids;
        res.requestDigestNeeded = false;
        return res;
    }

    public static IrpResponse newUnsuccessfulResponse(int opCode, int responseCode) {
        IrpResponse res = new IrpResponse(opCode, responseCode);
        res.result = "success";
        return res;
    }

    public static IrpResponse newErrorResponse(int opCode, int responseCode, String errorMessage) {
        IrpResponse res = new IrpResponse(opCode, responseCode);
        res.requestDigestNeeded = false;
        res.responseMessage = GlobalUtils.encodeString(errorMessage);
        res.result = "failed";
        return res;
    }

    public static IrpResponse newErrorResponse(int opCode, int responseCode, byte[] errorMessage) {
        IrpResponse res = new IrpResponse(opCode, responseCode);
        res.requestDigestNeeded = false;
        res.responseMessage = errorMessage;
        res.result = "failed";
        return res;
    }

    public static IrpResponse newVerifyIrsResponse(String doid, String result) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_VERIFY_IRS, IrpMessageCode.RC_SUCCESS, doid);
        res.requestDigestNeeded = false;
        res.responseMessage = GlobalUtils.encodeString(result);
        return res;
    }

    public static IrpResponse newVerifyIrsResponse(byte[] doid, byte[] errorMessage) {
        IrpResponse res = new IrpResponse(IrpMessageCode.OC_VERIFY_IRS, IrpMessageCode.RC_SUCCESS);
        res.requestDigestNeeded = false;
        res.doid = doid;
        res.responseMessage = errorMessage;
        return res;
    }

    public Map<String,String> getDoidValuesByMap() {
        Map<String,String> result = null;
        try{
            result = fromBytes2Map(this.doidValues);
        }
        catch(IrpMessageDecodeException e){
            e.printStackTrace();
        }

        return result;
    }

    public String getDoid() {
        return GlobalUtils.decodeString(this.doid);
    }

    public List<String> getDoidList() {
        List<String> doidStr = new ArrayList<String>();
        try{
            for(byte[] doidEl : doids){
                doidStr.add(GlobalUtils.decodeString(doidEl));
            }
            return doidStr;
        }catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    public String getResponseMessage() {
        return GlobalUtils.decodeString(this.responseMessage);
    }
}
